import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import javax.net.SocketFactory;


public class JSocketClient {
	private int timeout =5;

	public void callServer(String serverIp, int serverPort, String message) throws IOException {
		Socket scoket = createConnection(serverIp, serverPort);
		OutputStream out = scoket.getOutputStream();	
        writeWithPreLen(out,message.getBytes());

		closeConnection(scoket);
	}

	//发送报文
	public void writeWithPreLen(OutputStream out, byte[] data) throws IOException {
		byte[] dataToSend = new byte[8 + data.length];
		String preLen = String.format("%08d", data.length);
		ByteBuffer bb = ByteBuffer.wrap(dataToSend);
		bb.put(preLen.getBytes());
		bb.put(data);
		bb.compact();
		out.write(bb.array());
		out.flush();
	}

	//创建连接
	private Socket createConnection(String host, int port) throws UnknownHostException, IOException {
		Socket socket = SocketFactory.getDefault().createSocket();
		socket.connect(new InetSocketAddress(host, port), timeout * 1000);
		socket.setSoTimeout(timeout * 1000);
		socket.setTcpNoDelay(true);
		return socket;
	}
	
	//关闭连接
	private void closeConnection(Socket socket) {
        if (socket == null)
            return;
        try {
            socket.close();
        } catch (IOException e) {
        }
    }

	//读返回的报文
	public int read(InputStream in, OutputStream out, int prelen) throws IOException {
        int len = readlen(in, prelen);
        if (len <= 0)
            return 0;

        int count = 0;
        byte[] buf = new byte[1024];
        while (count < len) {
            int readlen = in.read(buf, 0, Math.min(len - count, 1024));
            //如果正在读取时对方关闭socket，则退出循环
            if (readlen == -1)
                break;
            out.write(buf, 0, readlen);
            count += readlen;
        }

        if (count != len) {
            throw new IOException("data is not receive completed:(" + len + "," + count + ")");
        }
        return len;
    }
	
	//判断读返回报文的长度
	public int readlen(InputStream in, int prelen) throws IOException {
        if (prelen <= 0)
            return 0;

        byte[] lendata = new byte[prelen];
        int count = 0, c, off = 0;

        while ((c = in.read()) != -1) {
            lendata[off++] = (byte) c;
            count++;
            if (count == prelen) {
                break;
            }
        }

        if (count != prelen)
            return 0;

        int len = Integer.parseInt(new String(lendata));
        return len;
    }
}
